Python 模拟执行 JavaScript 教程
目录
为什么需要这技能?
现代Web开发的核心逻辑已经不是全写在后端返回HTML了——前端渲染、接口参数加密、动态cookie生成全是JS的活儿。
举几个爬虫工程师或全栈摸鱼时常用的场景:
- 爬B站番剧/评论:需要先解析
bili_jct或_signature这类加密参数 - 爬电商平台商品库存:需要获取动态生成的
anti_scrape_token - 补全前后端分离项目的自动化测试:Python后端+前端加密需要模拟验证
今天我们就用PyExecJS(最通用的轻量级库)来解决这类问题,全程避开数学公式,重点讲「怎么把前端JS代码无缝搬到Python里跑」。
环境快速搭建
核心依赖
我们需要:
- PyExecJS库:Python和JS运行环境的中间桥梁
- JS运行环境:推荐Node.js(V8引擎,支持ES6+和第三方加密库,比Windows自带的JScript好用100倍)
一步步安装
1. 安装PyExecJS
2. 安装Node.js
直接去官网下载LTS版本(稳定不折腾):
安装完成后打开终端验证(Windows用PowerShell/CMD,Mac/Linux用Terminal):
3. 强制验证JS环境(关键!)
很多新手装完PyExecJS后,默认会用Windows自带的JScript(旧版不支持ES6+),这里要写个简单的代码强制检查并绑定Node.js:
实战:破解某球星站加密Token
我们用官方提供的SPA7爬虫练习站(https://spa7.scrape.center/)来练手——这个网站的每个球星卡片都有一个加密的`token`,只有拿到它才能请求完整的球星数据。
第一步:前端加密逻辑逆向
先别急着写Python!打开浏览器的开发者工具(F12),跟着我一步步找加密代码:
- 点击「Network」标签
- 刷新页面,找返回完整数据的请求(一般是带
api或detail后缀的) - 看请求参数,里面有个明显的加密字段
token - 点击「Initiator」标签,找到生成这个请求的JS文件位置
- 点进去后用Ctrl+F搜索
getToken(加密函数的常见命名)
第二步:提取加密代码
找到加密函数后,我们发现它依赖了crypto-js这个第三方库来做DES加密,那我们需要做两个准备:
- 下载完整的
crypto-js.min.js(压缩版,体积小) - 把加密函数和
crypto-js.min.js合并成一个JS文件,或者手动处理全局变量挂载
第三步:Python无缝调用
先整理加密文件(crypto_utils.js)
注意:Node.js默认不会把第三方库的内容挂载到全局对象,所以这里我们手动把压缩后的crypto-js包在一个自执行函数里,并返回CryptoJS:
再写Python调用代码
避坑指南+性能小技巧
1. 避坑:CryptoJS未定义
问题原因:Node.js环境下,直接require('crypto-js')不会挂载到全局,或者我们压缩后的代码没有正确返回。
解决方案:
- 用上面的「自执行函数+全局挂载」方法
- 或者在Python里通过
ctx.eval("const CryptoJS = require('crypto-js')")(前提是先在当前目录下npm install crypto-js)
2. 避坑:中文字符乱码
问题表现:如果加密对象里有中文,生成的Token在浏览器里验证失败。 解决方案:
- 确保JS文件是UTF-8 without BOM编码(不要用Windows记事本的默认编码)
- Python读取JS文件时必须指定
encoding='utf-8'
3. 性能优化:别每次都编译JS!
PyExecJS的编译过程是最耗时的(每次都会启动一个Node.js子进程),所以对于频繁调用的场景(比如爬取1000个球星的数据),必须:
- 把
execjs.compile()放在循环外,只执行一次 - 复用同一个
ctx对象
优化后的代码片段:
总结
通过今天的教程,我们掌握了:
- PyExecJS的环境搭建(强制绑定Node.js是关键)
- 前端加密逻辑的简单逆向(练习站)
- 加密代码的无缝迁移(解决全局变量、编码问题)
- 基础的性能优化(复用预编译的JS上下文)
如果遇到更复杂的加密(比如混淆后的JS、WebAssembly),可以:
- 先学习JS混淆的逆向工程(比如AST还原)
- 或者用Selenium/Playwright这种浏览器自动化工具(虽然性能慢,但不用逆向加密逻辑)
完整示例代码:GitHub仓库

